// useRef
// 语法
// const ref = useRef(initialValue)
// 返回值：useRef返回一个对象，对象的current属性指向传入的初始值
// 场景：
//  1. 获取dom元素，或者组件的实例
//  2. 存储值的作用(需要在组件渲染之间保持持久性数据时)
// 面试：和vue的ref有什么区别
//  1.获取值的方式  .value 和 .current
//  2.响应式  vue是响应式的，react只是拿到一个普通js对象。改变里面的属性不会触发组件的重新渲染。

// 实际应用：计时器

import { Button } from 'antd';
import { useRef, useState } from 'react';

const App = () => {
  // let num = 0;
  const num = useRef(0);
  const divRef = useRef<HTMLDivElement>(null);
  const [count, setCount] = useState(0);
  // 1.获取dom元素
  const handleClick = () => {
    console.dir(divRef.current);
  };
  // 2.存储值的作用
  // 此时发现 let num = 0; 由于改变状态触发组件重新渲染，num的值一直赋值为0，所以页面显示一直为0。
  // 解决方法：1.let num = 0;丢到 App函数外面定义 2.使用useRef定义num的值
  const changeCount = () => {
    setCount(count + 1);
    num.current = count; // 因为setCount是异步的，这样赋值num会比count小1，页面显示 count > num 1
  };

  // 3.计时器
  // let timer: NodeJS.Timeout | null = null;
  // 此时发现点击暂停没效，因为setInterval是异步的，所以清除定时器时，清除的是上一个定时器。而由于组件重新渲染，定时器不停在创建。
  // 解决：要把timer存起来，只有一个timer
  const timer = useRef<NodeJS.Timeout | null>(null);
  const [second, setSecond] = useState(0);
  const start = () => {
    timer.current = setInterval(() => {
      setSecond((second) => second + 1);
      // 错误写法 setSecond(second + 1); 会导致页面的second一直就那几个数字 原因：useState的setState是异步的，会阻断后续相同的操作
    }, 300);
  };

  const end = () => {
    if (timer) {
      clearInterval(timer.current);
      timer.current = null;
    }
  };
  return (
    <>
      <div>
        <button onClick={handleClick}>获取div元素</button>
      </div>
      <div ref={divRef}>
        <h1>Hello World</h1>
      </div>
      <div>
        <p>
          {count}:{num.current}
        </p>
        <Button onClick={changeCount}>+{count}</Button>
      </div>
      <div>
        <h3>计时器{second}</h3>
        <Button onClick={start}>开始</Button>
        <Button onClick={end}>暂停</Button>
      </div>
    </>
  );
};

export default App;
